home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.windows.x,news.answers,comp.answers
- Path: bloom-beacon.mit.edu!hookup!news.kei.com!MathWorks.Com!europa.eng.gtefsd.com!gatech!swrinde!cs.utexas.edu!uunet!visual!dbl
- From: dbl@visual.com (David B. Lewis)
- Subject: comp.windows.x Frequently Asked Questions (FAQ) 6/6
- Message-ID: <CM59M2.A9G@visual.com>
- Followup-To: poster
- Summary: useful information about the X Window System
- Reply-To: faq%craft@uunet.uu.net (X FAQ maintenance address)
- Organization: VISUAL, Inc.
- Date: Fri, 4 Mar 1994 14:30:02 GMT
- Approved: news-answers-request@MIT.Edu
- Expires: Sun, 3 Apr 1994 00:00:00 GMT
- Lines: 851
- Xref: bloom-beacon.mit.edu comp.windows.x:22118 news.answers:16019 comp.answers:4036
-
- Archive-name: x-faq/part6
- Last-modified: 1994/03/03
-
- ----------------------------------------------------------------------
- Subject: 133) Why doesn't XtDestroyWidget() actually destroy the widget?
-
- XtDestroyWidget() operates in two passes, in order to avoid leaving
- dangling data structures; the function-call marks the widget, which is not
- actually destroyed until your program returns to its event-loop.
-
- ----------------------------------------------------------------------
- Subject: 134) How do I query the user synchronously using Xt?
-
- It is possible to have code which looks like this trivial callback,
- which has a clear flow of control. The calls to AskUser() block until answer
- is set to one of the valid values. If it is not a "yes" answer, the code drops
- out of the callback and back to an event-processing loop:
-
- void quit(Widget w, XtPointer client, XtPointer call)
- {
- int answer;
- answer = AskUser(w, "Really Quit?");
- if (RET_YES == answer)
- {
- answer = AskUser(w, "Are You Really Positive?");
- if (RET_YES == answer)
- exit(0);
- }
- }
-
- A more realistic example might ask whether to create a file or whether
- to overwrite it.
- This is accomplished by entering a second event-processing loop and
- waiting until the user answers the question; the answer is returned to the
- calling function. That function AskUser() looks something like this, where the
- Motif can be replaced with widget-set-specific code to create some sort of
- dialog-box displaying the question string and buttons for "OK", "Cancel" and
- "Help" or equivalents:
-
- int AskUser(w, string)
- Widget w;
- char *string;
- {
- int answer=RET_NONE; /* some not-used marker */
- Widget dialog; /* could cache&carry, but ...*/
- Arg args[3];
- int n = 0;
- XtAppContext context;
-
- n=0;
- XtSetArg(args[n], XmNmessageString, XmStringCreateLtoR(string,
- XmSTRING_DEFAULT_CHARSET)); n++;
- XtSetArg(args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); n++;
- dialog = XmCreateQuestionDialog(XtParent(w), string, args, n);
- XtAddCallback(dialog, XmNokCallback, response, &answer);
- XtAddCallback(dialog, XmNcancelCallback, response, &answer);
- XtAddCallback(dialog, XmNhelpCallback, response, &answer);
- XtManageChild(dialog);
-
- context = XtWidgetToApplicationContext (w);
- while (answer == RET_NONE || XtAppPending(context)) {
- XtAppProcessEvent (context, XtIMAll);
- }
- XtDestroyWidget(dialog); /* blow away the dialog box and shell */
- return answer;
- }
-
- The dialog supports three buttons, which are set to call the same
- function when tickled by the user. The variable answer is set when the user
- finally selects one of those choices:
-
- void response(w, client, call)
- Widget w;
- XtPointer client;
- XtPointer call;
- {
- int *answer = (int *) client;
- XmAnyCallbackStruct *reason = (XmAnyCallbackStruct *) call;
- switch (reason->reason) {
- case XmCR_OK:
- *answer = RET_YES; /* some #define value */
- break;
- case XmCR_CANCEL:
- *answer = RET_NO;
- break;
- case XmCR_HELP:
- *answer = RET_HELP;
- break;
- default:
- return;
- }
- }
-
- and the code unwraps back to the point at which an answer was needed and
- continues from there.
-
- [Thanks to Dan Heller (argv@sun.com); note that the code in his book caches
- the dialog but neglects to make sure that the callbacks point to the
- current automatic "answer".]
-
- ----------------------------------------------------------------------
- Subject: 135) How do I determine the name of an existing widget?
- I have a widget ID and need to know what the name of that widget is.
-
- Users of R4 and later are best off using the XtName() function, which
- will work on both widgets and non-widget objects.
-
- If you are still using R3, you can use this simple bit of code to do
- what you want. Note that it depends on the widget's internal data structures
- and is not necessarily portable to future versions of Xt, including R4.
-
- #include <X11/CoreP.h>
- #include <X11/Xresource.h>
- String XtName (widget)
- Widget widget; /* WILL work with non-widget objects */
- {
- return XrmNameToString(widget->core.xrm_name);
- }
-
- [7/90; modified with suggestion by Larry Rogers (larry@boris.webo.dg.com) 9/91]
-
- ----------------------------------------------------------------------
- Subject: 136) Why do I get a BadDrawable error drawing to XtWindow(widget)?
- I'm doing this in order to get a window into which I can do Xlib graphics
- within my Xt-based program:
-
- > canvas = XtCreateManagedWidget ( ...,widgetClass,...) /* drawing area */
- > ...
- > window = XtWindow(canvas); /* get the window associated with the widget */
- > ...
- > XDrawLine (...,window,...); /* produces error */
-
- The window associated with the widget is created as a part of the
- realization of the widget. Using a window id of None ("no window") could
- create the error that you describe. It is necessary to call XtRealizeWidget()
- before attempting to use the window associated with a widget.
- Note that the window will be created after the XtRealizeWidget() call,
- but that the server may not have actually mapped it yet, so you should also
- wait for an Expose event on the window before drawing into it.
-
- ----------------------------------------------------------------------
- Subject: 137) Where can I get documentation on Xaw, the Athena widget set?
-
- Check ftp.x.org in /pub/R5untarred/mit/hardcopy for the originals
- of documentation distributed with X11R5.
-
- ----------------------------------------------------------------------
- Subject: 138) What's the difference between actions and callbacks?
-
- Actions and callbacks may be closely tied; the user may click a mouse-button
- in an object's window, causing an action procedure in that particular object
- to be called. As part of its processing of the event, the action procedure
- may inform the application via a callback registered on the object. However,
- callbacks can be given for any reason, including some that don't arise as a
- result of user action; and many actions don't result in any notification to
- the application.
-
- Callbacks generally are a means of interaction between the user interface
- (UI) and some other piece of code interested in the "results"; the interested
- party to which the data is communicated is usually the application's back-end
- functions but may be another widget in a related part of the UI. For
- example, a text widget invokes a callback to say "the user just entered this
- text string; never mind what I had to do to get it or what X events took
- place."
-
- In object-oriented programming terminology, callback lists are messages
- defined by the widget class by which the widget istance notifies another
- entity that something significant has happened to the widget.
-
- Actions, however, constitute a widget's repertoire of internal i/o
- behaviors. Actions are not about results; actions are about "how", not
- "what" gets done. The text widget may define a dozen or two actions which
- define how the user can manipulate the text; the procedures for removing a
- line of text or switching two words can be associated with particular X event
- sequences (and in fact often rely on particular types of events).
-
- Actions are (in OOP terminology) methods of the widget class by which the
- widget responds to some external stimulus (one or more X events).
-
- To avoid confusing yourself on the issue of actions vs. callbacks, try
- thinking of actions defined by an application as methods *of the application*
- -- applications may define actions, as well -- by which the application
- responds to one or more X events (and happens to be handed an object handle
- as part of the method argument list). Similarly, callback handlers registered
- by an application with a widget can be thought of as methods of the
- application which respond to messages from a widget or widgets.
-
- [Thanks to Michael Johnson (michael@maine.maine.edu) and to Kerry Kimbrough]
-
- ----------------------------------------------------------------------
- Subject: 139) How do I simulate a button press/release event for a widget?
-
- You can do this using XSendEvent(); it's likely that you're not setting
- the window field in the event, which Xt needs in order to match to the widget
- which should receive the event.
- If you're sending events to your own application, then you can use
- XtDispatchEvent() instead. This is more efficient than XSendEvent() in that you
- avoid a round-trip to the server.
- Depending on how well the widget was written, you may be able to call
- its action procedures in order to get the effects you want.
-
- [courtesy Mark A. Horstman (mh2620@sarek.sbc.com), 11/90]
-
- ----------------------------------------------------------------------
- Subject: 140) Can I make Xt or Xlib calls from a signal handler?
-
- No. Xlib and Xt have no mutual exclusion for protecting critical
- sections. If your signal handler makes such a call at the wrong time (which
- might be while the function you are calling is already executing), it can leave
- the library in an inconsistent state. Note that the ANSI C standard points
- out that behavior of a signal handler is undefined if the signal handler calls
- any function other than signal() itself, so this is not a problem specific to
- Xlib and Xt; the POSIX specification mentions other functions which may be
- called safely but it may not be assumed that these functions are called by
- Xlib or Xt functions.
- You can work around the problem by setting a flag in the interrupt
- handler and later checking it with a work procedure or a timer event which
- has previously been added.
- R6 Xt will have support for signal handlers; there will be a
- mechanism to set a flag in a signal handler and XtAppNextEvent will notice
- that the flag has been set, and call the associated callbacks.
-
- Note: the article in The X Journal 1:4 and the example in O'Reilly
- Volume 6 are in error.
-
- [Thanks to Pete Ware (ware@cis.ohio-state.edu) and Donna Converse
- (converse@x.org), 5/92]
-
- An alternate solution is to create a pipe and add the read side of the pipe
- as an input event with XtAppAddInput; then write a byte to the write side of
- the pipe with your signal handler (write is re-entrant). The callback for the
- read side of the pipe reads the byte and does the actual processing that you
- intended. You may want the byte to be the signal number unless your callback
- handles only one kind.
-
- [Thanks to Steve Kappel (stevek@apertus.com)]
-
- ----------------------------------------------------------------------
- Subject: 141) What are these "Xlib sequence lost" errors?
-
- You may see these errors if you issue Xlib requests from an Xlib error
- handler, or, more likely, if you make calls which generate X requests to Xt or
- Xlib from a signal handler, which you shouldn't be doing in any case.
-
- ----------------------------------------------------------------------
- Subject: 142) How can my Xt program handle socket, pipe, or file input?
-
- It's very common to need to write an Xt program that can accept input
- both from a user via the X connection and from some other file descriptor, but
- which operates efficiently and without blocking on either the X connection or
- the other file descriptor.
- A solution is use XtAppAddInput(). After you open your file descriptor,
- use XtAppAddInput() to register an input handler. The input handler will be
- called every time there is something on the file descriptor requiring your
- program's attention. Write the input handler like you would any other Xt
- callback, so it does its work quickly and returns. It is important to use only
- non-blocking I/O system calls in your input handlers.
- Most input handlers read the file descriptor, although you can have an
- input handler write or handle exception conditions if you wish.
- Be careful when you register an input handler to read from a disk file.
- You will find that the function is called even when there isn't input pending.
- XtAppAddInput() is actually working as it is supposed to. The input handler is
- called whenever the file descriptor is READY to be read, not only when there is
- new data to be read. A disk file (unlike a pipe or socket) is almost always
- ready to be read, however, if only because you can spin back to the beginning
- and read data you've read before. The result is that your function will almost
- always be called every time around XtAppMainLoop(). There is a way to get the
- type of interaction you are expecting; add this line to the beginning of your
- function to test whether there is new data:
- if (ioctl(fd, FIONREAD, &n) == -1 || n == 0) return;
- But, because this is called frequently, your application is effectively in a
- busy-wait; you may be better off not using XtAppAddInput() and instead setting
- a timer and in the timer procedure checking the file for input.
-
- [courtesy Dan Heller (argv@ora.com), 8/90; mouse@larry.mcrcim.mcgill.edu 5/91;
- Ollie Jones (oj@pictel.com) 6/92]
-
- There are two alternatives: the simple one is to use XtAppAddTimeout instead
- of XtAppAddInput and check for input occasionally; the more complex solution,
- and perhaps the better one, is to popen or fork&exec a child which does
- blocking reads on the file, relaying what it has read to your application via
- a pipe or a socket. XtAppAddInput will work as expected on pipes and
- sockets.
-
- [Thanks to Kaleb Keithley (kaleb@x.org); 12/93]
-
- ----------------------------------------------------------------------
- Subject: 143) Why do I get a BadMatch error when calling XGetImage?
-
- The BadMatch error can occur if the specified rectangle goes off the edge of
- the screen. If you don't want to catch the error and deal with it, you can take
- the following steps to avoid the error:
-
- 1) Make a pixmap the same size as the rectangle you want to capture.
- 2) Clear the pixmap to background using XFillRectangle.
- 3) Use XCopyArea to copy the window to the pixmap.
- 4) If you get a NoExpose event, the copy was clean. Use XGetImage to grab the
- image from the pixmap.
- 5) If you get one or more GraphicsExpose events, the copy wasn't clean, and
- the x/y/width/height members of the GraphicsExpose event structures tell you
- the parts of the pixmap which aren't good.
- 6) Get rid of the pixmap; it probably takes a lot of memory.
-
- [10/92; thanks to Oliver Jones (oj@pictel.com)]
-
- ----------------------------------------------------------------------
- Subject: 144) How can my application tell if it is being run under X?
-
- A number of programs offer X modes but otherwise run in a straight
- character-only mode. The easiest way for an application to determine that it is
- running on an X display is to attempt to open a connection to the X server:
-
- display = XOpenDisplay(display_name);
- if (display)
- { do X stuff }
- else
- { do curses or something else }
- where display_name is either the string specified on the command-line following
- -display, by convention, or otherwise is (char*)NULL [in which case
- XOpenDisplay uses the value of $DISPLAY, if set].
-
- This is superior to simply checking for the existence a -display command-line
- argument or checking for $DISPLAY set in the environment, neither of which is
- adequate. [5/91]
-
- ----------------------------------------------------------------------
- Subject: 145) How do I make a "busy cursor" while my application is computing?
- Is it necessary to call XDefineCursor() for every window in my application?
-
- The easiest thing to do is to create a single InputOnly window that
- is as large as the largest possible screen; make it a child of your toplevel
- window (which must be realized) and it will be clipped to that window, so it
- won't affect any other application. (It needs to be as big as the largest
- possible screen in case the user enlarges the window while it is busy or
- moves elsewhere within a virtual desktop.) Substitute "toplevel" with your
- top-most widget here (similar code should work for Xlib-only applications;
- just use your top Window):
-
- unsigned long valuemask;
- XSetWindowAttributes attributes;
-
- /* Ignore device events while the busy cursor is displayed. */
- valuemask = CWDontPropagate | CWCursor;
- attributes.do_not_propagate_mask = (KeyPressMask | KeyReleaseMask |
- ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
- attributes.cursor = XCreateFontCursor(XtDisplay(toplevel), XC_watch);
-
- /* The window will be as big as the display screen, and clipped by
- its own parent window, so we never have to worry about resizing */
- XCreateWindow(XtDisplay(toplevel), XtWindow(toplevel), 0, 0,
- 65535, 65535, (unsigned int) 0, 0, InputOnly,
- CopyFromParent, valuemask, &attributes);
-
- where the maximum size above could be replaced by the real size of the screen,
- particularly to avoid servers which have problems with windows larger than
- 32767.
-
- When you want to use this busy cursor, map and raise this window; to go back to
- normal, unmap it. This will automatically keep you from getting extra mouse
- events; depending on precisely how the window manager works, it may or may not
- have a similar effect on keystrokes as well.
-
- In addition, note also that most of the Xaw widgets support an XtNcursor
- resource which can be temporarily reset, should you merely wish to change the
- cursor without blocking pointer events.
-
- [thanks to Andrew Wason (aw@cellar.bae.bellcore.com), Dan Heller
- (argv@sun.com), and mouse@larry.mcrcim.mcgill.edu; 11/90,5/91]
-
- ----------------------------------------------------------------------
- Subject: 146) How do I fork without hanging my parent X program?
-
- An X-based application which spawns off other Unix processes which
- continue to run after it is closed typically does not vanish until all of its
- children are terminated; the children inherit from the parent the open X
- connection to the display.
- What you need to do is fork; then, immediately, in the child process,
- close (ConnectionNumber(XtDisplay(widget)));
- to close the file-descriptor in the display information. After this do your
- exec. You will then be able to exit the parent.
- Alternatively, before exec'ing make this call, which causes the file
- descriptor to be closed on exec.
- (void) fcntl(ConnectionNumber(XDisplay), F_SETFD, 1);
-
- [Thanks to Janet Anstett (anstettj@tramp.Colorado.EDU), Gordon Freedman
- (gjf00@duts.ccc.amdahl.com); 2/91. Greg Holmberg (holmberg@frame.com), 3/93.]
-
- ----------------------------------------------------------------------
- Subject: 147) Why doesn't anything appear when I run this simple program?
-
- > ...
- > the_window = XCreateSimpleWindow(the_display,
- > root_window,size_hints.x,size_hints.y,
- > size_hints.width,size_hints.height,BORDER_WIDTH,
- > BlackPixel(the_display,the_screen),
- > WhitePixel(the_display,the_screen));
- > ...
- > XSelectInput(the_display,the_window,ExposureMask|ButtonPressMask|
- > ButtonReleaseMask);
- > XMapWindow(the_display,the_window);
- > ...
- > XDrawLine(the_display,the_window,the_GC,5,5,100,100);
- > ...
-
- You are right to map the window before drawing into it. However, the
- window is not ready to be drawn into until it actually appears on the screen --
- until your application receives an Expose event. Drawing done before that will
- generally not appear. You'll see code like this in many programs; this code
- would appear after window was created and mapped:
- while (!done)
- {
- XNextEvent(the_display,&the_event);
- switch (the_event.type) {
- case Expose: /* On expose events, redraw */
- XDrawLine(the_display,the_window,the_GC,5,5,100,100);
- break;
- ...
- }
- }
-
- Note that there is a second problem: some Xlib implementations don't
- set up the default graphics context to have correct foreground/background
- colors, so this program could previously include this code:
- ...
- the_GC_values.foreground=BlackPixel(the_display,the_screen); /* e.g. */
- the_GC_values.background=WhitePixel(the_display,the_screen); /* e.g. */
- the_GC = XCreateGC(the_display,the_window,
- GCForeground|GCBackground,&the_GC_values);
- ...
-
- Note: the code uses BlackPixel and WhitePixel to avoid assuming that 1 is
- black and 0 is white or vice-versa. The relationship between pixels 0 and 1
- and the colors black and white is implementation-dependent. They may be
- reversed, or they may not even correspond to black and white at all.
-
- Also note that actually using BlackPixel and WhitePixel is usually the wrong
- thing to do in a finished program, as it ignores the user's preference for
- foreground and background.
-
- And also note that you can run into the same situation in an Xt-based program
- if you draw into the XtWindow(w) right after it has been realized; it may
- not yet have appeared.
-
- ----------------------------------------------------------------------
- Subject: 148) What is the difference between a Screen and a screen?
-
- The 'Screen' is an Xlib structure which includes the information about
- one of the monitors or virtual monitors which a single X display supports. A
- server can support several independent screens. They are numbered unix:0.0,
- unix:0.1, unix:0.2, etc; the 'screen' or 'screen_number' is the second digit --
- the 0, 1, 2 which can be thought of as an index into the array of available
- Screens on this particular Display connection.
- The macros which you can use to obtain information about the particular
- Screen on which your application is running typically have two forms -- one
- which takes a Screen and one with takes both the Display and the screen_number.
- In Xt-based programs, you typically use XtScreen(widget) to determine
- the Screen on which your application is running, if it uses a single screen.
- (Part of the confusion may arise from the fact that some of the macros
- which return characteristics of the Screen have "Display" in the names --
- XDisplayWidth, XDisplayHeight, etc.)
-
- ----------------------------------------------------------------------
- Subject: 149) Can XGetWindowAttributes get a window's background pixel/pixmap?
-
- No. Once set, the background pixel or pixmap of a window cannot be
- re-read by clients. The reason for this is that a client can create a pixmap,
- set it to be the background pixmap of a window, and then free the pixmap. The
- window keeps this background, but the pixmap itself is destroyed. If you're
- sure a window has a background pixel (not a pixmap), you can use XClearArea()
- to clear a region to the background color and then use XGetImage() to read
- back that pixel. However, this action alters the contents of the window, and
- it suffers from race conditions with exposures. [courtesy Dave Lemke of NCD
- and Stuart Marks of Sun]
-
- Note that the same applies to the border pixel/pixmap. This is a
- (mis)feature of the protocol which allows the server is free to manipulate the
- pixel/pixmap however it wants. By not requiring the server to keep the
- original pixel or pixmap, some (potentially a lot of) space can be saved.
- [courtesy Jim Fulton, then of X Consortium]
-
- ----------------------------------------------------------------------
- Subject: 150) How do I create a transparent window?
-
- A completely transparent window is easy to get -- use an InputOnly
- window. In order to create a window which is *mostly* transparent, you have
- several choices:
- - the SHAPE extension first released with X11R4 offers an easy way to
- make non-rectangular windows, so you can set the shape of the window to fit the
- areas where the window should be nontransparent; however, not all servers
- support the extension.
- - a machine-specific method of implementing transparent windows for
- particular servers is to use an overlay plane supported by the hardware. Note
- that there is no X notion of a "transparent color index".
- - a generally portable solution is to use a large number of tiny
- windows, but this makes operating on the application as a unit difficult.
- - a final answer is to consider whether you really need a transparent
- window or if you would be satisfied with being able to overlay your application
- window with information; if so, you can draw into separate bitplanes in colors
- that will appear properly.
-
- [thanks to der Mouse, mouse@lightning.McRCIM.McGill.EDU, 3/92; see also
- The X Journal 1:4 for a more complete answer, including code samples for this
- last option]
-
- ----------------------------------------------------------------------
- Subject: 151) Why doesn't GXxor produce mathematically-correct color values?
-
- When using GXxor you may expect that drawing with a value of black on a
- background of black, for example, should produce white. However, the drawing
- operation does not work on RGB values but on colormap indices. The color that
- the resulting colormap index actually points to is undefined and visually
- random unless you have actually filled it in yourself. [On many X servers Black
- and White often 0/1 or 1/0; programs taking advantage of this mathematical
- coincidence will break.]
- If you want to be combining colors with GXxor, then you should be
- allocating a number of your own color cells and filling them with your chosen
- pre-computed values.
- If you want to use GXxor simply to switch between two colors, then you
- can take the shortcut of setting the background color in the GC (graphics
- context) to 0 and the foreground color to a value such that when it draws over
- red, say, the result is blue, and when it draws over blue the result is red.
- This foreground value is itself the XOR of the colormap indices of red and
- blue.
-
- [Thanks to Chris Flatters (cflatter@zia.aoc.nrao.EDU) and Ken Whaley
- (whaley@spectre.pa.dec.com), 2/91]
-
- ----------------------------------------------------------------------
- Subject: 152) Why does every color I allocate show up as black?
-
- Make sure you're using 16 bits and not 8. The red, green, and blue
- fields of an XColor structure are scaled so that 0 is nothing and 65535 is
- full-blast. If you forget to scale (using, for example, 0-255 for each color)
- the XAllocColor function will perform correctly but the resulting color is
- usually black.
-
- [Thanks to Paul Asente, asente@adobe.com, 7/91]
-
- ----------------------------------------------------------------------
- Subject: 153) Why do I get a protocol error when creating a cursor (sic)?
-
- You may have had this code working on a monochrome system by
- coincidence. Cursor pixmaps must always have a depth of 1; when you create
- the cursor pixmap use the depth of 1 rather than the default depth of the
- screen.
-
- ----------------------------------------------------------------------
- Subject: 154) Why can't my program get a standard colormap?
- I have an image-processing program which uses XGetRGBColormap() to get the
- standard colormap, but it doesn't work.
-
- XGetRGBColormap() when used with the property XA_RGB_DEFAULT_MAP does
- not create a standard colormap -- it just returns one if one already exists.
- Use xstdcmap or do what it does in order to create the standard colormap first.
-
- [1/91; from der Mouse (mouse@larry.mcrcim.mcgill.edu)]
-
- ----------------------------------------------------------------------
- Subject: 155) Why does the pixmap I copy to the screen show up as garbage?
-
- The initial contents of pixmaps are undefined. This means that most
- servers will allocate the memory and leave around whatever happens to be there
- -- which is usually garbage. You probably want to clear the pixmap first using
- XFillRectangle() with a function of GXcopy and a foreground pixel of whatever
- color you want as your background (or 0L if you are using the pixmap as a
- mask). [courtesy Dave Lemke of NCD and Stuart Marks of Sun]
-
- ----------------------------------------------------------------------
- Subject: 156) How can I most quickly send an image to the X server?
-
- The fastest mechanism may be to use an XImage and the shared-memory
- extension to reduce the transmission time.
- The MIT-SHM code, documentation, and example client programs can be
- found on the X11R5 source tape; many vendors also support the extension.
-
- ----------------------------------------------------------------------
- Subject: 157) How do I check whether a window ID is valid?
- My program has the ID of a window on a remote display. I want to check whether
- the window exists before doing anything with it.
-
- Because X is asynchronous, there isn't a guarantee that the window
- would still exist between the time that you got the ID and the time you sent an
- event to the window or otherwise manipulated it. What you should do is send the
- event without checking, but install an error handler to catch any BadWindow
- errors, which would indicate that the window no longer exists. This scheme
- will work except on the [rare] occasion that the original window has been
- destroyed and its ID reallocated to another window.
- You can use this scheme to make a function which checks the validity
- of a window; you can make this operation almost synchronous by calling
- XSync() after the request, although there is still no guarantee that the
- window will exist after the result (unless the sterver is grabbed). On the
- whole, catching the error rather than pre-checking is preferable.
-
- [courtesy Ken Lee (klee@synoptics.com), 4/90; 12/93]
-
- ----------------------------------------------------------------------
- Subject: 158) Can I have two applications draw to the same window?
-
- Yes. The X server assigns IDs to windows and other resources (actually,
- the server assigns some bits, the client others), and any application that
- knows the ID can manipulate the resource [almost any X server resource, except
- for GCs and private color cells, can be shared].
- The problem you face is how to disseminate the window ID to multiple
- applications. A simple way to handle this (and which solves the problem of the
- applications' running on different machines) is in the first application to
- create a specially-named property on the root-window and put the window ID into
- it. The second application then retrieves the property, whose name it also
- knows, and then can draw whatever it wants into the window.
- [Note: this scheme works iff there is only one instance of the first
- application running, and the scheme is subject to the limitations mentioned
- in the Question about using window IDs on remote displays.]
- Note also that you will still need to coordinate any higher-level
- cooperation among your applications.
- Note also that two processes can share a window but should not try to
- use the same server connection. If one process is a child of the other, it
- should close down the connection to the server and open its own connection.
- Note also that Display IDs and GC values describe addresses local
- to an application and cannot be transmitted to another application.
- Note also that several clients may draw to a window but for particular
- X events such as button-presses only one client can receive the event.
-
- [mostly courtesy Phil Karlton (karlton@wpd.sgi.com) 6/90]
-
- ----------------------------------------------------------------------
- Subject: 159) Why can't my program work with tvtwm or swm?
-
- A number of applications, including xwd, xwininfo, and xsetroot, do not
- handle the virtual root window which tvtwm and swm use; they typically return
- the wrong child of root. A general solution is to add this code or to use it in
- your own application where you would normally use RootWindow(dpy,screen):
-
- /* Function Name: GetVRoot
- * Description: Gets the root window, even if it's a virtual root
- * Arguments: the display and the screen
- * Returns: the root window for the client
- */
- #include <X11/Xatom.h>
- Window GetVRoot(dpy, scr)
- Display *dpy;
- int scr;
- {
- Window rootReturn, parentReturn, *children;
- unsigned int numChildren;
- Window root = RootWindow(dpy, scr);
- Atom __SWM_VROOT = None;
- int i;
-
- __SWM_VROOT = XInternAtom(dpy, "__SWM_VROOT", False);
- XQueryTree(dpy, root, &rootReturn, &parentReturn, &children, &numChildren);
- for (i = 0; i < numChildren; i++) {
- Atom actual_type;
- int actual_format;
- long nitems, bytesafter;
- Window *newRoot = NULL;
-
- if (XGetWindowProperty(dpy, children[i], __SWM_VROOT, 0, 1,
- False, XA_WINDOW, &actual_type, &actual_format, &nitems,
- &bytesafter, (unsigned char **) &newRoot) == Success && newRoot) {
- root = *newRoot;
- break;
- }
- }
-
- return root;
- }
-
- [courtesy David Elliott (dce@smsc.sony.com). Similar code is in ssetroot, a
- version of xsetroot distributed with tvtwm. 2/91]
-
- A header file by Andreas Stolcke of ICSI on ftp.x.org:contrib/vroot.h
- functions similarly by providing macros for RootWindow and DefaultRootWindow;
- code can include this header file first to run properly in the presence of a
- virtual desktop.
-
- (Note the possible race condition.)
-
- ----------------------------------------------------------------------
- Subject: 160) Can I rely on a server which offers backing store?
-
- You can assume only that the X server has the capability of doing
- backing store and that it might do so and keep your application's visuals
- up-to-date without your program's involvement; however, the X server can run
- out of resources at any time, so you must be able to handle the exposure
- events yourself. You cannot rely on a server which offers backing store to
- maintain your windows' contents on your behalf.
-
- ----------------------------------------------------------------------
- Subject: 161) How do I catch the "close window" event to avoid "fatal IO error"?
-
- Several windows managers offer a function such as f.kill or f.delete
- which sends a message to the application that it should delete its window;
- this is usually interpreted as a shutdown message.
- The application needs to catch the WM_DELETE_WINDOW client message.
- There is a good example in the xcalc sources in X11R5.
- Motif-based applications should in addition set the resource
- XmNdeleteResponse on the top-level shell to XmDO_NOTHING, whether they are
- using the Motif window manager or not.
- If the application doesn't handle this message the window manager may
- wind up calling XKillClient, which disconnects the client from the display and
- typically gives an Xlib error along the lines of "fatal IO error 32 (Broken
- pipe)".
-
- [Thanks to Kaleb Keithley, kaleb@x.org; 11/93]
-
- ----------------------------------------------------------------------
- Subject: 162) How do I keep a window from being resized by the user?
-
- Resizing the window is done through the window manager; window managers
- can pay attention to the size hints your application places on the window, but
- there is no guarantee that the window manager will listen. You can try setting
- the minimum and maximum size hints to your target size and hope for the best.
- Note that you may wish to reconsider your justification for this
- restriction.
-
- ----------------------------------------------------------------------
- Subject: 163) How do I keep a window in the foreground at all times?
-
- It's rather antisocial for an application to constantly raise itself
- [e.g. by tracking VisibilityNotify events] so that it isn't overlapped --
- imagine the conflict between two such programs running.
- The only sure way to have your window appear on the top of the stack
- is to make the window override-redirect; this means that you are temporarily
- assuming window-management duties while the window is up, so you want to do
- this infrequently and then only for short periods of time (e.g. for popup
- menus or other short parameter-setting windows).
-
- [thanks to der Mouse (mouse@larry.mcrcim.mcgill.edu); 7/92]
-
- ----------------------------------------------------------------------
- Subject: 164) How do I make text and bitmaps blink in X?
-
- There is no easy way. Unless you're willing to depend on some sort of
- extension (as yet non-existent), you have to arrange for the blinking yourself,
- either by redrawing the contents periodically or, if possible, by playing games
- with the colormap and changing the color of the contents.
-
- [Thanks to mouse@larry.mcrcim.mcgill.edu (der Mouse), 7/91]
-
- ----------------------------------------------------------------------
- Subject: 165) How do I get a double-click in Xlib?
-
- Users of Xt have the support of the translation manager to help
- get notification of double-clicking.
- There is no good way to get only a double-click in Xlib, because the
- protocol does not provide enough support to do double-clicks. You have to do
- client-side timeouts, unless the single-click action is such that you can defer
- actually taking it until you next see an event from the server. Thus, you
- have to do timeouts, which means system-dependent code. On most UNIXish
- implementations, you can use XConnectionNumber to get the file descriptor of
- the X connection and then use select() or something similar on that.
- Note that many user-interface references suggest that a double-click
- be used to extend the action indicated by a single-click; if this is the case
- in your interface then you can execute the first action and as a compromise
- check the timestamp on the second event to determine whether it, too, should
- be the single-click action or the double-click action.
-
- [Thanks to mouse@larry.mcrcim.mcgill.edu (der Mouse), 4/93]
-
- ----------------------------------------------------------------------
- Subject: 166) How do I render rotated text?
-
- Xlib intentionally does not provide such sophisticated graphics
- capabilities, leaving them up to server-extensions or clients-side graphics
- libraries.
- Your only choice, if you want to stay within the core X protocol, is to
- render the text into a pixmap, read it back via XGetImage(), rotate it "by
- hand" with whatever matrices you want, and put it back to the server via
- XPutImage(); more specifically:
- 1) create a bitmap B and write your text to it.
- 2) create an XYBitmap image I from B (via XGetImage).
- 3) create an XYBitmap Image I2 big enough to handle the transformation.
- 4) for each x,y in I2, I2(x,y) = I(a,b) where
- a = x * cos(theta) - y * sin(theta)
- b = x * sin(theta) + y * cos(theta)
- 5) render I2
- Note that you should be careful how you implement this not to lose
- bits; an algorithm based on shear transformations may in fact be better.
- The high-level server-extensions and graphics packages available for X
- also permit rendering of rotated text: Display PostScript, PEX, PHiGS, and GKS,
- although most are not capable of arbitrary rotation and probably do not use the
- same fonts that would be found on a printer.
- In addition, if you have enough access to the server to install a font
- on it, you can create a font which consists of letters rotated at some
- predefined angle. Your application can then itself figure out placement of each
- glyph.
-
- [courtesy der Mouse (mouse@larry.mcrcim.mcgill.edu), Eric Taylor
- (etaylor@wilkins.bmc.tmc.edu), and Ken Lee (klee@synoptics.com), 11/90;
- Liam Quin (lee@sq.com), 12/90]
-
- InterViews (C++ UI toolkit, in the X contrib software) has support for
- rendering rotated fonts in X. It could be one source of example code.
- [Brian R. Smith (brsmith@cs.umn.edu), 3/91]
- Another possibility is to use the Hershey Fonts; they are
- stroke-rendered and can be used by X by converting them into XDrawLine
- requests. [eric@pencom.com, 10/91]
-
- The xrotfont program by Alan Richardson (mppa3@syma.sussex.ac.uk)
- (posted to comp.sources.x July 14 1992) paints a rotated font by implementing
- the method above and by using an outline (Hershey) font.
- The xvertext package by Alan Richardson (mppa3@syma.sussex.ac.uk) is a
- set of functions to facilitate the writing of text at any angle. It is on
- ftp.x.org as contrib/xvertext.5.0.shar.Z.
-
- O'Reilly's X Resource Volume 3 includes information from HP about
- modifications to the X fonts server which provide for rotated and scaled text.
- The modifications are on ftp.x.org in contrib/hp_xlfd_enhancements.
-
- ----------------------------------------------------------------------
- Subject: 167) Why doesn't my multi-threaded X program work (sic) ?
-
- You cannot use non-thread aware, non-reentrant libraries with threads.
-
- If you must do this, you have only one choice: call the functions from the
- initial thread only.
-
- Why opening windows from other threads causes protocol errors can be
- explained easily: you are accessing shared resources (the display
- structure, the connection to the display, static data in the Xlib) from
- a number of threads at the same time, without using any form of
- exclusive access control.
-
- [Thanks to casper@fwi.uva.nl (Casper H.S. Dik)]
-
- Support for multi-threaded X programs (Xlib and Xt) will be in X11R6.
-
- ----------------------------------------------------------------------
- Subject: 168) What is the X Registry? (How do I reserve names?)
-
- There are places in the X Toolkit, in applications, and in the X
- protocol that define and use string names. The context is such that conflicts
- are possible if different components use the same name for different things.
- The X Consortium maintains a registry of names in these domains:
- orgainization names, selection names, selection targets, resource types,
- application classes, and class extension record types; and several others.
- The list as of 7/91 is in the directory mit/doc/Registry on the R5
- tape. The current Registry is also available by sending "send docs registry"
- to the xstuff mail server.
- To register names (first come, first served) or to ask questions send
- to xregistry@x.org; be sure to include a postal address for confirmation.
-
- [11/90; condensed from Asente/Swick Appendix H; 1/94]
- ----------------------------------------------------------------------
-
-
- David B. Lewis faq%craft@uunet.uu.net
-
- "Just the FAQs, ma'am." -- Joe Friday
- --
- David B. Lewis Temporarily at but not speaking for Visual, Inc.
- day: dbl@visual.com evening: david%craft@uunet.uu.net
-